Attribute VB_Name = "modLimitWindowSize"
Option Explicit

Private Type POINTAPI
        X As Long
        Y As Long
End Type

Private Type MINMAXINFO
        ptReserved As POINTAPI
        ptMaxSize As POINTAPI
        ptMaxPosition As POINTAPI
        ptMinTrackSize As POINTAPI
        ptMaxTrackSize As POINTAPI
End Type

Private Declare Function CallWindowProc Lib "USER32" Alias "CallWindowProcA" ( _
                ByVal lpPrevWndFunc As Long, _
                ByVal hWnd As Long, _
                ByVal Msg As Long, _
                ByVal wParam As Long, _
                ByVal lParam As Long _
) As Long

Private Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" ( _
                ByVal hWnd As Long, _
                ByVal nIndex As Long, _
                ByVal dwNewLong As Long _
) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
                pDest As Any, _
                pSource As Any, _
                ByVal ByteLen As Long _
)

Private Const GWL_WNDPROC = (-4)
Private Const WM_GETMINMAXINFO = &H24

Dim OldProc As Long
Dim mhWnd As Long

Dim MaxWidth As Long
Dim MinWidth As Long
Dim MaxHeight As Long
Dim MinHeight As Long

Private Function WinProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If wMsg = WM_GETMINMAXINFO Then
        Dim mmif As MINMAXINFO
        CopyMemory mmif, ByVal lParam, Len(mmif)
        With mmif
            .ptMaxTrackSize.X = MaxWidth
            .ptMaxTrackSize.Y = MaxHeight
            .ptMinTrackSize.X = MinWidth
            .ptMinTrackSize.Y = MinHeight
        End With
        CopyMemory ByVal lParam, mmif, Len(mmif)
        WinProc = 1
        Exit Function
    End If
    WinProc = CallWindowProc(OldProc, hWnd, wMsg, wParam, lParam)
End Function

Public Sub LimitWindowSize(ByVal hWnd As Long, Optional wMax As Long, Optional hMax As Long, Optional wMin As Long, Optional hMin As Long)
    If OldProc <> 0 Then Exit Sub
    MaxWidth = wMax
    MaxHeight = hMax
    MinWidth = wMin
    MinHeight = hMin
    
    mhWnd = hWnd
    OldProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WinProc)
End Sub

Public Sub UnLimitWindowSize()
    If OldProc = 0 Then Exit Sub
    SetWindowLong mhWnd, GWL_WNDPROC, OldProc
    OldProc = 0
End Sub

